import express from 'express'
import { body, query, validationResult } from 'express-validator'
import { authenticateAdmin, generateAdminToken, requireSuperAdmin } from '../middleware/auth.js'
import { BusinessError, catchAsync } from '../middleware/errorHandler.js'
import { loginLimiter } from '../middleware/rateLimiter.js'
import { Admin } from '../models/index.js'
import { paginated, success } from '../utils/response.js'

const router = express.Router()

// 管理员登录
router.post('/login', loginLimiter, [
  body('username')
    .notEmpty()
    .withMessage('用户名不能为空'),
  body('password')
    .isLength({ min: 6 })
    .withMessage('密码至少6位'),
], catchAsync(async (req, res) => {
  const errors = validationResult(req)
  if (!errors.isEmpty()) {
    throw new BusinessError('参数验证失败', errors.array())
  }

  const { username, password } = req.body
  const ip = req.ip

  // 查找管理员
  const admin = await Admin.findByUsername(username)
  if (!admin) {
    throw new BusinessError('用户名或密码错误')
  }

  if (!admin.is_active) {
    throw new BusinessError('账户已被禁用')
  }

  // 验证密码
  const isValidPassword = await admin.validatePassword(password)
  if (!isValidPassword) {
    throw new BusinessError('用户名或密码错误')
  }

  // 更新登录信息
  await admin.updateLoginInfo(ip)

  // 生成JWT令牌
  const token = generateAdminToken(admin)

  // 构造符合前端期望的响应格式
  const loginData = {
    id: admin.id,
    userName: admin.username,
    role: [admin.role], // 转换为数组格式
    accessToken: token,
    refreshToken: token, // 暂时使用同一个token，后续可以实现真正的refresh token
    ...admin.toJSON(),
  }

  res.json(success(loginData, '登录成功'))
}))

// 获取管理员信息
router.get('/me', authenticateAdmin, catchAsync(async (req, res) => {
  res.json(success({
    admin: req.admin.toJSON(),
  }, '获取管理员信息成功'))
}))

// 管理员列表
router.get('/list', authenticateAdmin, requireSuperAdmin, [
  query('page').optional().isInt({ min: 1 }).withMessage('页码必须是正整数'),
  query('limit').optional().isInt({ min: 1, max: 100 }).withMessage('每页数量必须在1-100之间'),
  query('role').optional().isIn(['super_admin', 'admin']).withMessage('角色参数无效'),
  query('is_active').optional().isBoolean().withMessage('状态参数必须是布尔值'),
], catchAsync(async (req, res) => {
  const errors = validationResult(req)
  if (!errors.isEmpty()) {
    throw new BusinessError('参数验证失败', errors.array())
  }

  const { page = 1, limit = 20, role, is_active } = req.query

  const result = await Admin.getList({
    page: Number.parseInt(page),
    limit: Number.parseInt(limit),
    role,
    isActive: is_active !== undefined ? is_active === 'true' : undefined,
  })

  res.json(paginated(result.rows, {
    page: Number.parseInt(page),
    limit: Number.parseInt(limit),
    total: result.count,
    pages: Math.ceil(result.count / limit),
  }, '获取管理员列表成功'))
}))

// 创建管理员
router.post('/create', authenticateAdmin, requireSuperAdmin, [
  body('username')
    .isLength({ min: 3, max: 50 })
    .withMessage('用户名长度必须在3-50之间')
    .matches(/^\w+$/)
    .withMessage('用户名只能包含字母、数字和下划线'),
  body('password')
    .isLength({ min: 6 })
    .withMessage('密码至少6位'),
  body('email')
    .notEmpty()
    .withMessage('邮箱不能为空')
    .isEmail()
    .withMessage('邮箱格式不正确'),
  body('phone')
    .notEmpty()
    .withMessage('手机号不能为空')
    .isMobilePhone('zh-CN')
    .withMessage('请输入正确的手机号格式'),
  body('real_name')
    .optional()
    .isLength({ max: 50 })
    .withMessage('真实姓名不能超过50个字符'),
  body('role')
    .isIn(['super_admin', 'admin'])
    .withMessage('角色参数无效'),
], catchAsync(async (req, res) => {
  const errors = validationResult(req)
  if (!errors.isEmpty()) {
    throw new BusinessError('参数验证失败', errors.array())
  }

  const { username, password, email, phone, real_name, role } = req.body

  // 检查用户名是否已存在
  const existingAdmin = await Admin.findByUsername(username)
  if (existingAdmin) {
    throw new BusinessError('用户名已存在')
  }

  // 检查邮箱是否已存在
  const existingEmailAdmin = await Admin.findOne({ where: { email } })
  if (existingEmailAdmin) {
    throw new BusinessError('邮箱已被使用')
  }

  // 检查手机号是否已存在
  const existingPhoneAdmin = await Admin.findOne({ where: { phone } })
  if (existingPhoneAdmin) {
    throw new BusinessError('手机号已被使用')
  }

  // 创建管理员
  const admin = await Admin.createAdmin({
    username,
    password,
    email,
    phone,
    real_name,
    role,
  })

  res.json({
    code: 200,
    message: '管理员创建成功',
    data: {
      admin: admin.toJSON(),
    },
  })
}))

// 重置管理员密码
router.post('/reset-password', authenticateAdmin, requireSuperAdmin, [
  body('admin_id')
    .isInt({ min: 1 })
    .withMessage('管理员ID必须是正整数'),
  body('new_password')
    .isLength({ min: 6 })
    .withMessage('新密码至少6位'),
], catchAsync(async (req, res) => {
  const errors = validationResult(req)
  if (!errors.isEmpty()) {
    throw new BusinessError('参数验证失败', errors.array())
  }

  const { admin_id, new_password } = req.body

  // 查找管理员
  const admin = await Admin.findByPk(admin_id)
  if (!admin) {
    throw new BusinessError('管理员不存在')
  }

  // 不能重置自己的密码
  if (admin.id === req.admin.id) {
    throw new BusinessError('不能重置自己的密码')
  }

  // 重置密码
  await admin.resetPassword(new_password)

  res.json({
    code: 200,
    message: '密码重置成功',
  })
}))

// 编辑管理员信息
router.put('/edit/:id', authenticateAdmin, requireSuperAdmin, [
  body('username')
    .optional()
    .isLength({ min: 3, max: 50 })
    .withMessage('用户名长度必须在3-50个字符之间'),
  body('email')
    .optional()
    .isEmail()
    .withMessage('请输入正确的邮箱格式'),
  body('phone')
    .optional()
    .isMobilePhone('zh-CN')
    .withMessage('请输入正确的手机号格式'),
  body('real_name')
    .optional()
    .isLength({ min: 1, max: 50 })
    .withMessage('真实姓名长度必须在1-50个字符之间'),
  body('role')
    .optional()
    .isIn(['super_admin', 'admin'])
    .withMessage('角色必须是super_admin或admin'),
], catchAsync(async (req, res) => {
  const errors = validationResult(req)
  if (!errors.isEmpty()) {
    throw new BusinessError('参数验证失败', errors.array())
  }

  const adminId = Number.parseInt(req.params.id)
  const { username, email, phone, real_name, role } = req.body
  const currentAdmin = req.admin

  const admin = await Admin.findByPk(adminId)
  if (!admin) {
    throw new BusinessError('管理员不存在')
  }

  // 检查用户名是否已被其他管理员使用
  if (username && username !== admin.username) {
    const existingAdmin = await Admin.findOne({ where: { username } })
    if (existingAdmin && existingAdmin.id !== admin.id) {
      throw new BusinessError('该用户名已被其他管理员使用')
    }
  }

  // 检查邮箱是否已被其他管理员使用
  if (email && email !== admin.email) {
    const existingAdmin = await Admin.findOne({ where: { email } })
    if (existingAdmin && existingAdmin.id !== admin.id) {
      throw new BusinessError('该邮箱已被其他管理员使用')
    }
  }

  // 检查手机号是否已被其他管理员使用
  if (phone && phone !== admin.phone) {
    const existingAdmin = await Admin.findOne({ where: { phone } })
    if (existingAdmin && existingAdmin.id !== admin.id) {
      throw new BusinessError('该手机号已被其他管理员使用')
    }
  }

  // 不能修改自己的角色
  if (role && adminId === currentAdmin.id && role !== admin.role) {
    throw new BusinessError('不能修改自己的角色')
  }

  // 更新管理员信息
  const updateData = {}
  if (username !== undefined)
    updateData.username = username
  if (email !== undefined)
    updateData.email = email
  if (phone !== undefined)
    updateData.phone = phone
  if (real_name !== undefined)
    updateData.real_name = real_name
  if (role !== undefined)
    updateData.role = role

  await admin.update(updateData)

  res.json({
    code: 200,
    message: '管理员信息更新成功',
    data: {
      admin: admin.toJSON(),
    },
  })
}))

// 删除管理员
router.delete('/:id', authenticateAdmin, requireSuperAdmin, catchAsync(async (req, res) => {
  const adminId = Number.parseInt(req.params.id)
  const currentAdmin = req.admin

  // 不能删除自己
  if (adminId === currentAdmin.id) {
    throw new BusinessError('不能删除自己')
  }

  const admin = await Admin.findByPk(adminId)
  if (!admin) {
    throw new BusinessError('管理员不存在')
  }

  // 不能删除超级管理员
  if (admin.role === 'super_admin') {
    throw new BusinessError('不能删除超级管理员')
  }

  await admin.destroy()

  res.json({
    code: 200,
    message: '管理员删除成功',
  })
}))

// 更新管理员状态
router.put('/status', authenticateAdmin, requireSuperAdmin, [
  body('admin_id')
    .isInt({ min: 1 })
    .withMessage('管理员ID必须是正整数'),
  body('is_active')
    .isBoolean()
    .withMessage('状态必须是布尔值'),
], catchAsync(async (req, res) => {
  const errors = validationResult(req)
  if (!errors.isEmpty()) {
    throw new BusinessError('参数验证失败', errors.array())
  }

  const { admin_id, is_active } = req.body

  // 查找管理员
  const admin = await Admin.findByPk(admin_id)
  if (!admin) {
    throw new BusinessError('管理员不存在')
  }

  // 不能禁用自己
  if (admin.id === req.admin.id) {
    throw new BusinessError('不能禁用自己的账户')
  }

  // 更新状态
  admin.is_active = is_active
  await admin.save()

  res.json({
    code: 200,
    message: '状态更新成功',
    data: {
      admin: admin.toJSON(),
    },
  })
}))

// 退出登录
router.post('/logout', authenticateAdmin, catchAsync(async (req, res) => {
  res.json(success(null, '退出登录成功'))
}))

// 更新管理员个人信息
router.put('/profile', authenticateAdmin, [
  body('name')
    .optional()
    .isLength({ min: 1, max: 50 })
    .withMessage('姓名长度必须在1-50个字符之间'),
  body('nickname')
    .optional()
    .isLength({ min: 1, max: 100 })
    .withMessage('昵称长度必须在1-100个字符之间'),
  body('email')
    .optional()
    .isEmail()
    .withMessage('请输入正确的邮箱格式'),
  body('phone')
    .optional()
    .isMobilePhone('zh-CN')
    .withMessage('请输入正确的手机号格式'),
], catchAsync(async (req, res) => {
  const errors = validationResult(req)
  if (!errors.isEmpty()) {
    throw new BusinessError('参数验证失败', errors.array())
  }

  const { name, nickname, email, phone } = req.body
  const admin = req.admin

  // 检查邮箱是否已被其他管理员使用
  if (email && email !== admin.email) {
    const existingAdmin = await Admin.findOne({ where: { email } })
    if (existingAdmin && existingAdmin.id !== admin.id) {
      throw new BusinessError('该邮箱已被其他管理员使用')
    }
  }

  // 检查手机号是否已被其他管理员使用
  if (phone && phone !== admin.phone) {
    const existingAdmin = await Admin.findOne({ where: { phone } })
    if (existingAdmin && existingAdmin.id !== admin.id) {
      throw new BusinessError('该手机号已被其他管理员使用')
    }
  }

  // 更新管理员信息
  const updateData = {}
  if (name !== undefined)
    updateData.real_name = name
  if (nickname !== undefined)
    updateData.nickname = nickname
  if (email !== undefined)
    updateData.email = email
  if (phone !== undefined)
    updateData.phone = phone

  await admin.update(updateData)

  res.json({
    code: 200,
    message: '个人信息更新成功',
    data: {
      user: admin.toJSON(),
    },
  })
}))

// 修改管理员密码
router.put('/password', authenticateAdmin, [
  body('currentPassword')
    .notEmpty()
    .withMessage('请输入当前密码'),
  body('newPassword')
    .isLength({ min: 6, max: 50 })
    .withMessage('新密码长度必须在6-50个字符之间')
    .matches(/^(?=.*[a-z])(?=.*\d)/i)
    .withMessage('新密码必须包含至少一个字母和一个数字'),
  body('confirmPassword')
    .custom((value, { req }) => {
      if (value !== req.body.newPassword) {
        throw new Error('确认密码与新密码不一致')
      }
      return true
    }),
], catchAsync(async (req, res) => {
  const errors = validationResult(req)
  if (!errors.isEmpty()) {
    throw new BusinessError('参数验证失败', errors.array())
  }

  const { currentPassword, newPassword } = req.body
  const admin = req.admin

  // 验证当前密码
  const isCurrentPasswordValid = await admin.validatePassword(currentPassword)
  if (!isCurrentPasswordValid) {
    throw new BusinessError('当前密码错误')
  }

  // 检查新密码是否与当前密码相同
  const isSamePassword = await admin.validatePassword(newPassword)
  if (isSamePassword) {
    throw new BusinessError('新密码不能与当前密码相同')
  }

  // 更新密码
  await admin.update({ password: newPassword })

  res.json({
    code: 200,
    message: '密码修改成功',
  })
}))

export default router
